//
//	File: OyDirect3D9.h
//
#ifndef OYDIRECT3D9_H
#define OYDIRECT3D9_H

#include "../OyRenderer/OyRenderDevice.h"
#include "../OyGeneral/OyGeneral.h"
#include "OyDirect3D9_enum.h"
#include <d3d9.h>

class OySkinManager;
class OyD3D9Camera;
class OyD3D9VertexCacheManager;
class OyFontManager;

BOOL WINAPI DllEntryPoint( HINSTANCE hDll,
                           DWORD     fdwReason,
                           LPVOID    lpvRserved );



/**
 * Class definition for a Direct3D render device, implementing the
 * interface OyRenderDevice
 */
class OyDirect3D9 : public OyRenderDevice 
{
public:
	OyDirect3D9();
	virtual ~OyDirect3D9();

	// Manager function
	virtual OySkinManager* GetSkinManager(void) { return m_pSkinManager; }
	virtual OyVertexCacheManager* GetVertexCacheManager(void) { return m_pVCManager; }

	// Initialize:
	virtual HRESULT Init( HWND hWnd, const HWND *hWnd3D, int nNumhWnd, int nMinDepth, int nMinStencil );
	virtual void	OnDeviceReset(void);

	// Interface functions
	virtual HRESULT UseWindow(UINT nHwnd);
	virtual void    Release(void);
	virtual bool    IsRunning(void) { return m_bRunning; }
	virtual HRESULT BeginRendering(bool bClearPixel, bool bClearDepth, bool bClearStencil);
	virtual void    EndRendering();
	virtual void	FlushRenderBatch();
	virtual HRESULT Clear(bool bClearPixel, bool bClearDepth, bool bClearStencil);
	virtual void    SetClearColor(float fRed, float fGreen, float fBlue);
	virtual void    SetAmbientLight(float fRed, float fGreen, float fBlue);
	virtual void	GetScreenResolution(POINT* pt) { pt->x = m_dwScreenWidth;  pt->y = m_dwScreenHeight; }


	virtual HRESULT SetMode(OY_CAMERAMODE Mode);
	virtual HRESULT	SetViewPort(OY_VIEWPORT* pViewPort);
	virtual HRESULT	GetViewPort(OY_VIEWPORT* pViewPort);
	virtual void	SetClippingPlanes(float fNear, float fFar);
	virtual HRESULT	SetProjMatrixParams(float fFOV, float fAspect);
	// must normalized vector
	virtual HRESULT	SetViewMatrix3D(const OyVector4D& vcRight, const OyVector4D& vcUp, 
								const OyVector4D& vcDir, const OyVector4D& vcEyePos);
	// could be un-normalized vector
	virtual HRESULT	SetViewMatrixLookAt(const OyVector4D& vcPos, const OyVector4D& vcPoint, 
								const OyVector4D& vcWorldUp);


	virtual HRESULT	GetFrustrum(OyPlane* pPlane);
	virtual void	GetViewMatrix(float *pMat);
	virtual void	GetProjMatrix(float *pMat);
	virtual void	Transform2Dto3D(const POINT &pt, OyVector4D *vcOrig, OyVector4D *vcDir);
	virtual POINT	Transform3Dto2D(const OyVector4D &vcPoint);

	virtual void	BeginRenderText();
	virtual void	EndRenderText();
	virtual void	SetActiveFont(const char* FontName);
    virtual HRESULT CreateFontInManager(const char* FontName, const char* FontFilePath, bool bBold, bool bItalic, DWORD dwSize);
    virtual HRESULT DrawTextInPos(int xPos, int yPos, DWORD flag, float RealFontSize, UCHAR r, UCHAR g, UCHAR b,TCHAR* format, ...);
	virtual void	PreCacheChar(const TCHAR* sText);
	//
	LPDIRECT3DVERTEXDECLARATION9 GetVertexDeclaration(OY_VERTEXTYPE type);
	OyD3D9Camera* GetCurrentCamera() { return m_pCurrentCamera; }

public:
	// OyRenderDevice access Interface pointer in OyDirect3D9 DLL Model 
	static OyRenderDevice	*m_OyEngineRenderDevice;

private:
	static const int MAX_3DHWND			= 8;
	static const int MAX_FONT_STRING	= 256;

	HWND           m_hWndMain;						// application main window
	HWND           m_hWnd[MAX_3DHWND];				// 3D render window handle
	UINT           m_nNumhWnd;						// number of hwnds in array
	UINT           m_nActivehWnd;					// which one is active (0=main hWnd)
	DWORD          m_dwScreenWidth;					// screen width
	DWORD          m_dwScreenHeight;				// screen height
	DWORD          m_dwWidth;						// current viewport width
	DWORD          m_dwHeight;						// current viewport height
	bool           m_bWindowed;						// windowed mode?
	TCHAR          m_chAdapter[256];				// graphics adapter name
	bool           m_bRunning;						// after succesful initialization
	TCHAR		   m_FontString[MAX_FONT_STRING];	// max Font string output for rendering

	OySkinManager *m_pSkinManager;					// material and textures Manager
	OyVertexCacheManager *m_pVCManager;				// VertexCacheManager
	OyD3D9Camera  *m_pCurrentCamera;				// Active D3D9 camera 
	OyFontManager *m_pFontManager;					// Font generation and rendering Manager	
	
private:
	OyDirect3D9Enum			*m_pEnum;
	LPDIRECT3D9				m_pD3D;
	LPDIRECT3DDEVICE9		m_pDevice;
	LPDIRECT3DSWAPCHAIN9	m_pChain[MAX_3DHWND];
	LPDIRECT3DSURFACE9		m_pChainDepthSurface[MAX_3DHWND];
	D3DPRESENT_PARAMETERS	m_d3dpp;
	D3DCOLOR				m_ClearColor;
	bool					m_bIsSceneRunning;
	bool					m_bStencil;

	// cureent using D3D device info
	OyDEVICEINFO_D3DDEVICE  m_xDeviceINI;
	// below are device setting in INI file
	D3DDISPLAYMODE			m_DspmdINI;
	D3DFORMAT				m_fmtAINI;
	D3DFORMAT				m_fmtBINI;
	D3DMULTISAMPLE_TYPE		m_multiSampleINI;

	LPDIRECT3DVERTEXDECLARATION9 m_UPOSdecl;
	LPDIRECT3DVERTEXDECLARATION9 m_UPOSNORCOLTEXdecl;
	LPDIRECT3DVERTEXDECLARATION9 m_UTEXdecl;
	LPDIRECT3DVERTEXDECLARATION9 m_UCOLORdecl;
	LPDIRECT3DVERTEXDECLARATION9 m_ANIMdecl;
	LPDIRECT3DVERTEXDECLARATION9 m_THREETEXdecl;
	LPDIRECT3DVERTEXDECLARATION9 m_UTANdecl;
	LPDIRECT3DVERTEXDECLARATION9 m_FONTdecl;

	// start API
	HRESULT Go(void);
	HRESULT OnceInit(void);
	HRESULT CreateSwapChains(void);
	HRESULT CreateVertexDeclaration(void);
	void	OnDeviceLost(void);
	
};

#define GetRenderDevice()	OyDirect3D9::m_OyEngineRenderDevice

#endif